home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / java / io / LineNumberInputStream.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  9.4 KB  |  280 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)LineNumberInputStream.java    1.19 98/03/23
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.io;
  16.  
  17. /**
  18.  * This class is an input stream filter that provides the added 
  19.  * functionality of keeping track of the current line number. 
  20.  * <p>
  21.  * A line is a sequence of bytes ending with a carriage return 
  22.  * character (<code>'\r'</code>), a newline character 
  23.  * (<code>'\n'</code>), or a carriage return character followed 
  24.  * immediately by a linefeed character. In all three cases, the line 
  25.  * terminating character(s) are returned as a single newline character.
  26.  * <p>
  27.  * The line number begins at <code>0</code>, and is incremented by 
  28.  * <code>1</code> when a <code>read</code> returns a newline character.
  29.  *
  30.  * @author     Arthur van Hoff
  31.  * @version    1.19, 03/23/98
  32.  * @see        java.io.LineNumberReader
  33.  * @since      JDK1.0
  34.  * @deprecated This class incorrectly assumes that bytes adequately represent
  35.  *             characters.  As of JDK 1.1, the preferred way to operate on
  36.  *             character streams is via the new character-stream classes, which
  37.  *             include a class for counting line numbers.
  38.  */
  39. public
  40. class LineNumberInputStream extends FilterInputStream {
  41.     int pushBack = -1;
  42.     int lineNumber;
  43.     int markLineNumber;
  44.     int markPushBack = -1;
  45.     
  46.     /**
  47.      * Constructs a newline number input stream that reads its input 
  48.      * from the specified input stream. 
  49.      *
  50.      * @param      in   the underlying input stream.
  51.      */
  52.     public LineNumberInputStream(InputStream in) {
  53.     super(in);
  54.     }
  55.  
  56.     /**
  57.      * Reads the next byte of data from this input stream. The value 
  58.      * byte is returned as an <code>int</code> in the range 
  59.      * <code>0</code> to <code>255</code>. If no byte is available 
  60.      * because the end of the stream has been reached, the value 
  61.      * <code>-1</code> is returned. This method blocks until input data 
  62.      * is available, the end of the stream is detected, or an exception 
  63.      * is thrown. 
  64.      * <p>
  65.      * The <code>read</code> method of 
  66.      * <code>LineNumberInputStream</code> calls the <code>read</code> 
  67.      * method of the underlying input stream. It checks for carriage 
  68.      * returns and newline characters in the input, and modifies the 
  69.      * current line number as appropriate. A carriage-return character or 
  70.      * a carriage return followed by a newline character are both 
  71.      * converted into a single newline character. 
  72.      *
  73.      * @return     the next byte of data, or <code>-1</code> if the end of this
  74.      *             stream is reached.
  75.      * @exception  IOException  if an I/O error occurs.
  76.      * @see        java.io.FilterInputStream#in
  77.      * @see        java.io.LineNumberInputStream#getLineNumber()
  78.      */
  79.     public int read() throws IOException {
  80.     int c = pushBack;
  81.  
  82.     if (c != -1) {
  83.         pushBack = -1;
  84.     } else {
  85.         c = in.read();
  86.     }
  87.  
  88.     switch (c) {
  89.       case '\r':
  90.         pushBack = in.read();
  91.         if (pushBack == '\n') {
  92.         pushBack = -1;
  93.         }
  94.       case '\n':
  95.         lineNumber++;
  96.         return '\n';
  97.     }
  98.     return c;
  99.     }
  100.  
  101.     /**
  102.      * Reads up to <code>len</code> bytes of data from this input stream 
  103.      * into an array of bytes. This method blocks until some input is available.
  104.      * <p>
  105.      * The <code>read</code> method of 
  106.      * <code>LineNumberInputStream</code> repeatedly calls the 
  107.      * <code>read</code> method of zero arguments to fill in the byte array.
  108.      *
  109.      * @param      b     the buffer into which the data is read.
  110.      * @param      off   the start offset of the data.
  111.      * @param      len   the maximum number of bytes read.
  112.      * @return     the total number of bytes read into the buffer, or
  113.      *             <code>-1</code> if there is no more data because the end of
  114.      *             this stream has been reached.
  115.      * @exception  IOException  if an I/O error occurs.
  116.      * @see        java.io.LineNumberInputStream#read()
  117.      */
  118.     public int read(byte b[], int off, int len) throws IOException {
  119.     if (b == null) {
  120.         throw new NullPointerException();
  121.     } else if ((off < 0) || (off > b.length) || (len < 0) ||
  122.            ((off + len) > b.length) || ((off + len) < 0)) {
  123.         throw new IndexOutOfBoundsException();
  124.     } else if (len == 0) {
  125.         return 0;
  126.     }
  127.  
  128.     int c = read();
  129.     if (c == -1) {
  130.         return -1;
  131.     }
  132.     b[off] = (byte)c;
  133.  
  134.     int i = 1;
  135.     try {
  136.         for (; i < len ; i++) {
  137.         c = read();
  138.         if (c == -1) {
  139.             break;
  140.         }
  141.         if (b != null) {
  142.             b[off + i] = (byte)c;
  143.         }
  144.         }
  145.     } catch (IOException ee) {
  146.     }
  147.     return i;
  148.     }
  149.  
  150.     /**
  151.      * Skips over and discards <code>n</code> bytes of data from this 
  152.      * input stream. The <code>skip</code> method may, for a variety of 
  153.      * reasons, end up skipping over some smaller number of bytes, 
  154.      * possibly <code>0</code>. The actual number of bytes skipped is 
  155.      * returned.  If <code>n</code> is negative, no bytes are skipped.
  156.      * <p>
  157.      * The <code>skip</code> method of <code>LineNumberInputStream</code> creates 
  158.      * a byte array and then repeatedly reads into it until 
  159.      * <code>n</code> bytes have been read or the end of the stream has 
  160.      * been reached. 
  161.      *
  162.      * @param      n   the number of bytes to be skipped.
  163.      * @return     the actual number of bytes skipped.
  164.      * @exception  IOException  if an I/O error occurs.
  165.      * @see        java.io.FilterInputStream#in
  166.      */
  167.     public long skip(long n) throws IOException {
  168.     int chunk = 2048;             
  169.     long remaining = n;
  170.     byte data[];
  171.     int nr;
  172.  
  173.     if (n <= 0) {
  174.         return 0;
  175.     }
  176.     
  177.     data = new byte[chunk];
  178.     while (remaining > 0) {
  179.         nr = read(data, 0, (int) Math.min(chunk, remaining));
  180.         if (nr < 0) {
  181.         break;
  182.         }
  183.         remaining -= nr;
  184.     }
  185.     
  186.     return n - remaining;
  187.     }
  188.  
  189.     /**
  190.      * Sets the line number to the specified argument. 
  191.      *
  192.      * @param      lineNumber   the new line number.
  193.      */
  194.     public void setLineNumber(int lineNumber) {
  195.     this.lineNumber = lineNumber;
  196.     }
  197.  
  198.     /**
  199.      * Returns the current line number.
  200.      *
  201.      * @return     the current line number.
  202.      */
  203.     public int getLineNumber() {
  204.     return lineNumber;
  205.     }
  206.  
  207.    
  208.     /**
  209.      * Returns the number of bytes that can be read from this input 
  210.      * stream without blocking. 
  211.      * <p>
  212.      * Note that if the underlying input stream is able to supply 
  213.      * <i>k</i> input characters without blocking, the 
  214.      * <code>LineNumberInputStream</code> can guarantee only to provide 
  215.      * <i>k</i>/2 characters without blocking, because the 
  216.      * <i>k</i> characters from the underlyhing input stream might 
  217.      * consist of <i>k</i>/2 pairs of <code>'\r'</code> and 
  218.      * <code>'\n'</code>, which are converted to just 
  219.      * <i>k</i>/2 <code>'\n'</code> characters. 
  220.      *
  221.      * @return     the number of bytes that can be read from this input stream
  222.      *             without blocking.
  223.      * @exception  IOException  if an I/O error occurs.
  224.      * @see        java.io.FilterInputStream#in
  225.      */
  226.     public int available() throws IOException {
  227.     return (pushBack == -1) ? super.available()/2 : super.available()/2 + 1;
  228.     }
  229.  
  230.     /**
  231.      * Marks the current position in this input stream. A subsequent 
  232.      * call to the <code>reset</code> method repositions this stream at 
  233.      * the last marked position so that subsequent reads re-read the same bytes.
  234.      * <p>
  235.      * The <code>mark</code> method of 
  236.      * <code>LineNumberInputStream</code> remembers the current line 
  237.      * number in a private variable, and then calls the <code>mark</code> 
  238.      * method of the underlying input stream. 
  239.      *
  240.      * @param   readlimit   the maximum limit of bytes that can be read before
  241.      *                      the mark position becomes invalid.
  242.      * @see     java.io.FilterInputStream#in
  243.      * @see     java.io.LineNumberInputStream#reset()
  244.      */
  245.     public void mark(int readlimit) {
  246.     markLineNumber = lineNumber;
  247.         markPushBack   = pushBack;
  248.     in.mark(readlimit);
  249.     }
  250.  
  251.     /**
  252.      * Repositions this stream to the position at the time the 
  253.      * <code>mark</code> method was last called on this input stream. 
  254.      * <p>
  255.      * The <code>reset</code> method of 
  256.      * <code>LineNumberInputStream</code> resets the line number to be 
  257.      * the line number at the time the <code>mark</code> method was 
  258.      * called, and then calls the <code>reset</code> method of the 
  259.      * underlying input stream. 
  260.      * <p>
  261.      * Stream marks are intended to be used in
  262.      * situations where you need to read ahead a little to see what's in
  263.      * the stream. Often this is most easily done by invoking some
  264.      * general parser. If the stream is of the type handled by the
  265.      * parser, it just chugs along happily. If the stream is not of
  266.      * that type, the parser should toss an exception when it fails,
  267.      * which, if it happens within readlimit bytes, allows the outer
  268.      * code to reset the stream and try another parser.
  269.      *
  270.      * @exception  IOException  if an I/O error occurs.
  271.      * @see        java.io.FilterInputStream#in
  272.      * @see        java.io.LineNumberInputStream#mark(int)
  273.      */
  274.     public void reset() throws IOException {
  275.     lineNumber = markLineNumber;
  276.         pushBack   = markPushBack;
  277.     in.reset();
  278.     }
  279. }
  280.